﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Cci;
using Microsoft.Cci.MutableCodeModel;

namespace Mutator
{

    class ExpressionMutantGenerator : Microsoft.Cci.MutableCodeModel.MethodBodyCodeMutator
    {
        Random rand = new Random();
        public ExpressionMutantGenerator(IMetadataHost host)
            : base(host)
        {

        }
        public ExpressionMutantGenerator(IMetadataHost host, ISourceLocationProvider/*?*/ sourceLocationProvider)
            : base(host, sourceLocationProvider)
        {

        }

        public override IExpression Visit(Multiplication multiplication)
        {
            Console.WriteLine("++++++ multiplication");
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp1 = new Addition();
                newOp1.LeftOperand = multiplication.LeftOperand;
                newOp1.RightOperand = multiplication.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp1);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp2 = new Subtraction();
                newOp2.LeftOperand = multiplication.LeftOperand;
                newOp2.RightOperand = multiplication.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp2);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp3 = new Modulus();
                newOp3.LeftOperand = multiplication.LeftOperand;
                newOp3.RightOperand = multiplication.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp3);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp4 = new Division();
                newOp4.LeftOperand = multiplication.LeftOperand;
                newOp4.RightOperand = multiplication.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp4);
            }

            return this.Visit((BinaryOperation)multiplication);
        }
        public override IExpression Visit(Division division)
        {
            Console.WriteLine("++++++ division");
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp1 = new Addition();
                newOp1.LeftOperand = division.LeftOperand;
                newOp1.RightOperand = division.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp1);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp2 = new Subtraction();
                newOp2.LeftOperand = division.LeftOperand;
                newOp2.RightOperand = division.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp2);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp3 = new Modulus();
                newOp3.LeftOperand = division.LeftOperand;
                newOp3.RightOperand = division.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp3);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp4 = new Multiplication();
                newOp4.LeftOperand = division.LeftOperand;
                newOp4.RightOperand = division.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp4);
            }
            return this.Visit((BinaryOperation)division);
        }
        public override IExpression Visit(Addition addition)
        {
            Console.WriteLine("++++++ addition");
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp1 = new Multiplication();
                newOp1.LeftOperand = addition.LeftOperand;
                newOp1.RightOperand = addition.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp1);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp2 = new Subtraction();
                newOp2.LeftOperand = addition.LeftOperand;
                newOp2.RightOperand = addition.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp2);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp3 = new Modulus();
                newOp3.LeftOperand = addition.LeftOperand;
                newOp3.RightOperand = addition.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp3);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp4 = new Division();
                newOp4.LeftOperand = addition.LeftOperand;
                newOp4.RightOperand = addition.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp4);
            }

            return this.Visit((BinaryOperation)addition);
        }
        public override IExpression Visit(Subtraction subtraction)
        {
            Console.WriteLine("++++++ subtraction");
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp1 = new Addition();
                newOp1.LeftOperand = subtraction.LeftOperand;
                newOp1.RightOperand = subtraction.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp1);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp2 = new Multiplication();
                newOp2.LeftOperand = subtraction.LeftOperand;
                newOp2.RightOperand = subtraction.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp2);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp3 = new Modulus();
                newOp3.LeftOperand = subtraction.LeftOperand;
                newOp3.RightOperand = subtraction.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp3);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp4 = new Division();
                newOp4.LeftOperand = subtraction.LeftOperand;
                newOp4.RightOperand = subtraction.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp4);
            }
            return this.Visit((BinaryOperation)subtraction);
        }
        public override IExpression Visit(Modulus modulus)
        {
            Console.WriteLine("++++++ modulus");
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp1 = new Addition();
                newOp1.LeftOperand = modulus.LeftOperand;
                newOp1.RightOperand = modulus.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp1);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp2 = new Subtraction();
                newOp2.LeftOperand = modulus.LeftOperand;
                newOp2.RightOperand = modulus.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp2);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp3 = new Multiplication();
                newOp3.LeftOperand = modulus.LeftOperand;
                newOp3.RightOperand = modulus.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp3);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp4 = new Division();
                newOp4.LeftOperand = modulus.LeftOperand;
                newOp4.RightOperand = modulus.RightOperand;
                Mutants.mutated = true;
                return this.Visit(newOp4);
            }
            return this.Visit((BinaryOperation)modulus);
        }

        public override IExpression Visit(BitwiseAnd bitwiseAnd)
        {
            Console.WriteLine("++++++ bitwiseand");
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp1 = new BitwiseOr();
                newOp1.RightOperand = bitwiseAnd.RightOperand;
                newOp1.LeftOperand = bitwiseAnd.LeftOperand;
                Mutants.mutated = true;
                return this.Visit(newOp1);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp2 = new ExclusiveOr();
                newOp2.RightOperand = bitwiseAnd.RightOperand;
                newOp2.LeftOperand = bitwiseAnd.LeftOperand;
                Mutants.mutated = true;
                return this.Visit(newOp2);
            }

            return this.Visit((BinaryOperation)bitwiseAnd);
        }
        public override IExpression Visit(BitwiseOr bitwiseOr)
        {
            Console.WriteLine("++++++ bitwiseor");
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp1 = new BitwiseAnd();
                newOp1.RightOperand = bitwiseOr.RightOperand;
                newOp1.LeftOperand = bitwiseOr.LeftOperand;
                Mutants.mutated = true;
                return this.Visit(newOp1);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp2 = new ExclusiveOr();
                newOp2.RightOperand = bitwiseOr.RightOperand;
                newOp2.LeftOperand = bitwiseOr.LeftOperand;
                Mutants.mutated = true;
                return this.Visit(newOp2);
            }

            return this.Visit((BinaryOperation)bitwiseOr);
        }
        public override IExpression Visit(ExclusiveOr exclusiveOr)
        {
            Console.WriteLine("++++++ exclusiveor");
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp1 = new BitwiseOr();
                newOp1.RightOperand = exclusiveOr.RightOperand;
                newOp1.LeftOperand = exclusiveOr.LeftOperand;
                Mutants.mutated = true;
                return this.Visit(newOp1);
            }
            Mutants.mutantNumber++;
            if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
            {
                Mutants.toVisit.Remove(Mutants.mutantNumber);
                BinaryOperation newOp2 = new BitwiseAnd();
                newOp2.RightOperand = exclusiveOr.RightOperand;
                newOp2.LeftOperand = exclusiveOr.LeftOperand;
                Mutants.mutated = true;
                return this.Visit(newOp2);
            }
            return this.Visit((BinaryOperation)exclusiveOr);
        }

        public override IExpression Visit(BinaryOperation operation)
        {
            //Console.WriteLine("++++++ expression_binaryoperation");
            INamespaceTypeReference typeRef = operation.Type as INamespaceTypeReference;
            if (typeRef == null) return base.Visit(operation);
            if (typeRef.Equals(this.host.PlatformType.SystemInt32))
            {

                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp1 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32 };
                    newOp1.Value = 1;
                    Mutants.mutated = true;
                    return base.Visit(newOp1);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp2 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32 };
                    newOp2.Value = 0;
                    Mutants.mutated = true;
                    return base.Visit(newOp2);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp3 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32 };
                    newOp3.Value = -1;
                    Mutants.mutated = true;
                    return base.Visit(newOp3);
                }

                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp4 = new UnaryNegation();
                    newOp4.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp4);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp5 = new UnaryPlus();
                    newOp5.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp5);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp6 = new OnesComplement();
                    newOp6.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp6);
                }


            }
            else if (typeRef.Equals(this.host.PlatformType.SystemBoolean))
            {
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp8 = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean };
                    Mutants.mutated = true;
                    return base.Visit(newOp8);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp9 = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean };
                    Mutants.mutated = true;
                    return base.Visit(newOp9);
                }

            }
            else if (typeRef.Equals(this.host.PlatformType.SystemFloat32))
            {
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp10 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemFloat32 };
                    newOp10.Value = rand.Next(1, int.MaxValue);
                    Mutants.mutated = true;
                    return base.Visit(newOp10);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp11 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemFloat32 };
                    newOp11.Value = 0;
                    Mutants.mutated = true;
                    return base.Visit(newOp11);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp12 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemFloat32 };
                    newOp12.Value = rand.Next(int.MinValue, 0);
                    Mutants.mutated = true;
                    return base.Visit(newOp12);
                }

                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp13 = new UnaryNegation();
                    newOp13.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp13);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp14 = new UnaryPlus();
                    newOp14.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp14);
                }


            }
            else if (typeRef.Equals(this.host.PlatformType.SystemInt16))
            {
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp15 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt16 };
                    newOp15.Value = rand.Next(1, int.MaxValue);
                    Mutants.mutated = true;
                    return base.Visit(newOp15);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp16 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt16 };
                    newOp16.Value = 0;
                    Mutants.mutated = true;
                    return base.Visit(newOp16);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp17 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt16 };
                    newOp17.Value = rand.Next(int.MinValue, 0);
                    Mutants.mutated = true;
                    return base.Visit(newOp17);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp18 = new UnaryNegation();
                    newOp18.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp18);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp19 = new UnaryPlus();
                    newOp19.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp19);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp20 = new OnesComplement();
                    newOp20.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp20);
                }

            }
            else if (typeRef.Equals(this.host.PlatformType.SystemInt64))
            {
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp21 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt64 };
                    newOp21.Value = rand.Next(1, int.MaxValue);
                    Mutants.mutated = true;
                    return base.Visit(newOp21);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp22 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt64 };
                    newOp22.Value = 0;
                    Mutants.mutated = true;
                    return base.Visit(newOp22);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp23 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt64 };
                    newOp23.Value = rand.Next(int.MinValue, 0);
                    Mutants.mutated = true;
                    return base.Visit(newOp23);
                }

                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp24 = new UnaryNegation();
                    newOp24.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp24);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp25 = new UnaryPlus();
                    newOp25.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp25);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp26 = new OnesComplement();
                    newOp26.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp26);
                }
            }
            else if (typeRef.Equals(this.host.PlatformType.SystemInt8))
            {
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp27 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt8 };
                    newOp27.Value = rand.Next(1, int.MaxValue);
                    Mutants.mutated = true;
                    return base.Visit(newOp27);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp28 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt8 };
                    newOp28.Value = 0;
                    Mutants.mutated = true;
                    return base.Visit(newOp28);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp29 = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt8 };
                    newOp29.Value = rand.Next(int.MinValue, 0);
                    Mutants.mutated = true;
                    return base.Visit(newOp29);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp30 = new UnaryNegation();
                    newOp30.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp30);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp31 = new UnaryPlus();
                    newOp31.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp31);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp32 = new OnesComplement();
                    newOp32.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp32);
                }

            }
            return base.Visit(operation);
        }

        public override IExpression Visit(UnaryOperation operation)
        {
            //Console.WriteLine("++++++ expression_unaryoperation");

            ITypeReference typeRef = operation.Type as INamespaceTypeReference;
            if (typeRef == null) return operation;
            if (typeRef.Equals(this.host.PlatformType.SystemInt32))
            {

                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp1 = new CompileTimeConstant();
                    newOp1.Value = rand.Next(1, int.MaxValue);
                    Mutants.mutated = true;
                    return base.Visit(newOp1);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp2 = new CompileTimeConstant();
                    newOp2.Value = 0;
                    Mutants.mutated = true;
                    return base.Visit(newOp2);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp3 = new CompileTimeConstant();
                    newOp3.Value = rand.Next(int.MinValue, 0);
                    Mutants.mutated = true;
                    return base.Visit(newOp3);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp4 = new UnaryNegation();
                    newOp4.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp4);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp5 = new UnaryPlus();
                    newOp5.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp5);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    UnaryOperation newOp6 = new OnesComplement();
                    newOp6.Operand = operation;
                    Mutants.mutated = true;
                    return base.Visit(newOp6);
                }
            }
            else if (typeRef.Equals(this.host.PlatformType.SystemBoolean))
            {
                //UnaryOperation newOp7 = new LogicalNot();
                //newOp7.Operand = operation;
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp8 = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean };
                    Mutants.mutated = true;
                    return base.Visit(newOp8);
                }
                Mutants.mutantNumber++;
                if (!Mutants.mutated && Mutants.toVisit.Contains(Mutants.mutantNumber))
                {
                    Mutants.toVisit.Remove(Mutants.mutantNumber);
                    CompileTimeConstant newOp9 = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean };
                    Mutants.mutated = true;
                    return base.Visit(newOp9);
                }

            }

            return base.Visit(operation);

        }



    }
}